home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / mach / ds5000.md / machUNIXSyscall.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  6.9 KB  |  250 lines

  1. /* 
  2.  * machUNIXSyscall.c --
  3.  *
  4.  * This file calls the Unix Compatibility stubs.  Normally, the assembly
  5.  * version of this file will get used, not this file.
  6.  *    
  7.  *    Copyright (C) 1989 Digital Equipment Corporation.
  8.  *    Permission to use, copy, modify, and distribute this software and
  9.  *    its documentation for any purpose and without fee is hereby granted,
  10.  *    provided that the above copyright notice appears in all copies.  
  11.  *    Digital Equipment Corporation makes no representations about the
  12.  *    suitability of this software for any purpose.  It is provided "as is"
  13.  *    without express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/mach/ds5000.md/machUNIXSyscall.c,v 9.15 92/06/16 17:08:45 shirriff Exp $ SPRITE (DECWRL)";
  18. #endif not lint
  19.  
  20. #include "sprite.h"
  21. #include "status.h"
  22. #include "machConst.h"
  23. #include "machInt.h"
  24. #include "mach.h"
  25. #include "proc.h"
  26. #include "vm.h"
  27. #include "user/sys/types.h"
  28. #include "user/sys/file.h"
  29. #include "user/fs.h"
  30. #include "user/sys/wait.h"
  31. #include "user/sys/time.h"
  32. #include "user/sys/resource.h"
  33. #include "user/sys/uio.h"
  34. #include "stat.h"
  35. #include "ultrixSignal.h"
  36. #include "sys.h"
  37. #include "fs.h"
  38. #include "fsdm.h"
  39. #include "fslcl.h"    /* Directory format */
  40. #include "sys/types.h"
  41.  
  42. /*
  43.  * System call entry structure.  Note that this is different than the one
  44.  * in the sys directory.  This should be converted over to that format
  45.  * with the addition of the name field.
  46.  */
  47. typedef struct {
  48.     char        *name;
  49.     int            numArgs;
  50.     ReturnStatus    (*func)();
  51. } SyscallInfo;
  52.  
  53. /*
  54.  * Values for system call tracing:
  55.  *
  56.  *    0:     Use the fast assembly language interface and don't trace 
  57.  *        anything.
  58.  *    1:     Use the slower C interface but no trace printing.
  59.  *    > 1:     Use the slower C interface and trace system calls.
  60.  */
  61.  
  62. /*
  63.  * The code to disable migration for processes using the compatibility
  64.  * library is in the slower C interface...
  65.  */
  66. #ifdef CANT_MIGRATE_COMPAT
  67. int machUNIXSyscallTrace = 0;
  68. #else /* CANT_MIGRATE_COMPAT */
  69. int machUNIXSyscallTrace = 0;
  70. #endif /* CANT_MIGRATE_COMPAT */
  71.  
  72. extern Mach_State    *machCurStatePtr;
  73.  
  74. #define UNIX_SIG_RETURN        103
  75. #define UNIX_LONG_JUMP_RETURN    139
  76.  
  77. extern int sysCallNum;
  78.  
  79.  
  80. /*
  81.  * ----------------------------------------------------------------------------
  82.  *
  83.  * MachUNIXSyscallNew --
  84.  *
  85.  *    Try to handle the new given UNIX system call.
  86.  *    Note that this routine is called only if (machUNIXSyscallTrace > 0)
  87.  *    or under special conditions.
  88.  *
  89.  * Results:
  90.  *    TRUE if this was really a UNIX system call.
  91.  *
  92.  * Side effects:
  93.  *    None.
  94.  *
  95.  * ----------------------------------------------------------------------------
  96.  */
  97. Boolean
  98. MachUNIXSyscallNew()
  99. {
  100.     unsigned        *regs;
  101.     int            args[6];
  102.     ReturnStatus    status;
  103.     int            type;
  104.     int            numArgs;
  105. #ifdef CANT_MIGRATE_COMPAT
  106.     Proc_ControlBlock    *procPtr;
  107. #endif /* CANT_MIGRATE_COMPAT */
  108.  
  109.     /*
  110.      * See if we got a UNIX system call.  Unix passes the system call type
  111.      * in v0.
  112.      */
  113.     type = machCurStatePtr->userState.regState.regs[V0];
  114.     sysCallNum = type;
  115.     machCurStatePtr->userState.savedV0 = type;
  116.     machCurStatePtr->userState.savedA3 =
  117.         machCurStatePtr->userState.regState.regs[A3];
  118.     if (type < 0 || type >= MACH_MAX_UNIX_SYSCALL) {
  119.     printf("MachUNIXSyscallNew failed with type %d\n", type);
  120.     return(FALSE);
  121.     }
  122.  
  123. #ifdef CANT_MIGRATE_COMPAT
  124.     /*
  125.      * We don't want to migrate processes that are making unix-compatible calls.
  126.      */
  127.     procPtr = Proc_GetCurrentProc();
  128.     if (!(procPtr->genFlags & PROC_DONT_MIGRATE)) {
  129.     Proc_NeverMigrate(procPtr);
  130.     }
  131. #endif /* CANT_MIGRATE_COMPAT */
  132.     
  133.     numArgs = sysUnixSysCallTable[type].numArgs;
  134.     regs = machCurStatePtr->userState.regState.regs;
  135.     if (numArgs > 4) {
  136.     if (Vm_CopyIn(4 * (numArgs - 4), regs[SP] + 16, args) != SUCCESS) {
  137.         regs[V0] = Compat_MapCode(SYS_ARG_NOACCESS);
  138.         regs[A3] = 1;
  139.         return(TRUE);
  140.     }
  141.     }
  142.     switch (numArgs) {
  143.     case 0:
  144.         if (machUNIXSyscallTrace > 1) {
  145.         printf("MachUNIXSyscallNew: syscall%d() => ", type);
  146.         }
  147.         status = sysUnixSysCallTable[type].func();
  148.         break;
  149.     case 1:
  150.         if (machUNIXSyscallTrace > 1) {
  151.         printf("MachUNIXSyscallNew: syscall%d(%x) => ", 
  152.             type,
  153.             regs[A0]);
  154.         }
  155.         status = sysUnixSysCallTable[type].func(regs[A0]);
  156.         break;
  157.     case 2:
  158.         if (machUNIXSyscallTrace > 1) {
  159.         printf("MachUNIXSyscallNew: syscall%d(%x, %x) => ", 
  160.             type,
  161.             regs[A0], regs[A1]);
  162.         }
  163.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1]);
  164.         break;
  165.     case 3:
  166.         if (machUNIXSyscallTrace > 1) {
  167.         printf("MachUNIXSyscallNew: syscall%d(%x, %x, %x) => ", 
  168.             type,
  169.             regs[A0], regs[A1], regs[A2]);
  170.         }
  171.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  172.                          regs[A2]);
  173.         break;
  174.     case 4:
  175.         if (machUNIXSyscallTrace > 1) {
  176.         printf("MachUNIXSyscallNew: syscall%d(%x, %x, %x, %x) => ", 
  177.             type,
  178.             regs[A0], regs[A1], regs[A2], regs[A3]);
  179.         }
  180.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  181.                          regs[A2], regs[A3]);
  182.         break;
  183.     case 5: 
  184.         if (machUNIXSyscallTrace > 1) {
  185.         printf("MachUNIXSyscallNew: syscall%d(%x, %x, %x, %x, %x) => ", 
  186.             type,
  187.             regs[A0], regs[A1], regs[A2], regs[A3], args[0]);
  188.         }
  189.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  190.                          regs[A2], regs[A3], args[0]);
  191.         break; 
  192.     case 6:
  193.         if (machUNIXSyscallTrace > 1) {
  194.         printf("MachUNIXSyscallNew: syscall%d(%x, %x, %x, %x, %x, %x) => ", 
  195.             type,
  196.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  197.             args[1]);
  198.         }
  199.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  200.                          regs[A2], regs[A3], args[0],
  201.                          args[1]);
  202.         break; 
  203.     case 7:
  204.         if (machUNIXSyscallTrace > 1) {
  205.         printf("MachUNIXSyscallNew: syscall%d(%x, %x, %x, %x, %x, %x, %x) => ", 
  206.             type,
  207.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  208.             args[1], args[2]);
  209.         }
  210.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1],
  211.                          regs[A2], regs[A3], args[0],
  212.                          args[1], args[2]);
  213.         break;
  214.     case 8:
  215.         if (machUNIXSyscallTrace > 1) {
  216.         printf("MachUNIXSyscallNew: syscall%d(%x, %x, %x, %x, %x, %x, %x, %x) => ", 
  217.             type,
  218.             regs[A0], regs[A1], regs[A2], regs[A3], args[0],
  219.             args[1], args[2], args[3]);
  220.         }
  221.         status = sysUnixSysCallTable[type].func(regs[A0], regs[A1], 
  222.                          regs[A2], regs[A3], args[0],
  223.                          args[1], args[2], args[3]);
  224.     default:
  225.         panic("Too many args to UNIX system call\n");
  226.         break;
  227.     }
  228.     /*
  229.      * The UNIX stubs looks at a3 to decide what to do.  If a3 == 1 then
  230.      * v0 has the UNIX error code and the stub will stuff the error
  231.      * into errno.  If a3 == 0 the V0 has the return value.
  232.      */
  233.     if (type != MACH_UNIX_LONG_JUMP_RETURN && type != MACH_UNIX_SIG_RETURN) {
  234.     if (status >= 0) {
  235.         regs[V0] = status;
  236.         regs[A3] = 0;
  237.     } else {
  238.         regs[V0] = Proc_GetActualProc()->unixErrno;
  239.         regs[A3] = 1;
  240.     }
  241.     }
  242.     if (machUNIXSyscallTrace > 1) {
  243.     printf("V0 = %x A3 = %x\n", regs[V0], regs[A3]);
  244.     }
  245.  
  246.     machCurStatePtr->userState.regState.pc += 4;
  247.  
  248.     return(TRUE);
  249. }
  250.